package com.freewater.library.lending.reservedsheet.infrastructure.dao;

import com.freewater.library.lending.reservedsheet.model.BookReservedRecord;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import org.apache.commons.lang3.Validate;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;

import java.util.List;
import java.util.Optional;

public class BookReservedRecordDao extends SimpleJpaRepository<BookReservedRecord, Long> {

    private final EntityManager entityManager;

    public BookReservedRecordDao(EntityManager entityManager) {
        super(BookReservedRecord.class, entityManager);
        this.entityManager = entityManager;
    }

    public boolean existsByUnique(BookReservedRecord.Unique unique) {
        String hql = "select count(*) from BookReservedRecord t where t.qrCode = :qrCode " +
                "and t.reservedBy = :reservedBy and t.reservedAt = :reservedAt ";
        Query query = this.entityManager.createQuery(hql, Long.class);
        query.setParameter("qrCode", unique.getQrCode());
        query.setParameter("reservedBy", unique.getReservedBy());
        query.setParameter("reservedAt", unique.getReservedAt());
        Long count = (Long) query.getSingleResult();
        return count != null && count > 0;
    }

    public Optional<BookReservedRecord> findByUnique(BookReservedRecord.Unique unique) {
        String hql = "from BookReservedRecord t where t.qrCode = :qrCode " +
                "and t.reservedBy = :reservedBy and t.reservedAt = :reservedAt ";
        Query query = this.entityManager.createQuery(hql, BookReservedRecord.class);
        query.setParameter("qrCode", unique.getQrCode());
        query.setParameter("reservedBy", unique.getReservedBy());
        query.setParameter("reservedAt", unique.getReservedAt());
        List<BookReservedRecord> resultList = query.getResultList();
        Validate.isTrue(resultList.isEmpty() || resultList.size() == 1);
        return resultList.isEmpty() ? Optional.empty() : Optional.of(resultList.get(0));
    }
}
